package br.com.processo.persistencia.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.hibernate.Session;
import org.hibernate.ejb.EntityManagerImpl;

import br.com.processo.modelo.Identificavel;

public abstract class GenericDAOImpl<T extends Identificavel> implements GenericDAO<T> {

	@PersistenceContext(unitName = "processodb")
	protected EntityManager	entityManager;

	private final Class<T>	persistentClass;

	@SuppressWarnings("unchecked")
	public GenericDAOImpl() {
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
				.getActualTypeArguments()[0];
//		EntityManagerFactory emf = Persistence.createEntityManagerFactory("processodb");
//		entityManager = emf.createEntityManager();
	}

	@Override
	public T localizaObjeto(Long objId) {
		return this.entityManager.getReference(this.persistentClass, objId);
	}

	@Override
	public List<T> listaObjetos() {
		TypedQuery<T> query = this.entityManager.createQuery(String.format("FROM %s", this.persistentClass.getName()),
				this.persistentClass);
		return query.getResultList();
	}

	@Override
	public void deletaObjetos() {
		TypedQuery<T> query = this.entityManager.createQuery(
				String.format("DELETE FROM %s", this.persistentClass.getName()), this.persistentClass);
		query.executeUpdate();

	}

	@Override
	public void removeObjeto(Long objId) {
		T obj = localizaObjeto(objId);

		if (obj != null) {
			this.entityManager.remove(obj);
		}
	}

	@Override
	public T insereObjeto(T obj) {
		return this.entityManager.merge(obj);
	}

	public Session getSession() {
		Session session;
		if (this.entityManager.getDelegate() instanceof EntityManagerImpl) {
			EntityManagerImpl entityManagerImpl = (EntityManagerImpl) this.entityManager.getDelegate();
			session = entityManagerImpl.getSession();
		} else {
			session = (Session) this.entityManager.getDelegate();
		}
		return session;
	}

	public EntityManager getEntityManager() {
		return this.entityManager;
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

}
